home *** CD-ROM | disk | FTP | other *** search
/ 10,000 Great Games / 10,000 Great Games.iso / Product / 66 / data1.cab / Source_Files / Src / Parse.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  4KB  |  226 lines

  1. #include "stdafx.h"
  2.  
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. static char val[128], *val_end = val + sizeof(val);
  7. static char lab[128], *lab_end = lab + sizeof(lab);
  8. static int line_no;
  9. static char *data_start, *data_current, *data_end;
  10.  
  11. cParse::cParse(cParse **list, const char *_label, const char *_value)
  12. {
  13.     add_end((cList **)list);
  14.     
  15.     label = strdup(_label);
  16.     value = strdup(_value);
  17.     
  18.     line = line_no;
  19. }
  20.  
  21. cParse::cParse(cParse **list, cParse *orig)
  22.     add_end((cList **)list);
  23.     
  24.     label = strdup(orig->label);
  25.     value = strdup(orig->value);
  26.     
  27.     line = orig->line;
  28. }            
  29.  
  30. cParse::~cParse()
  31. {
  32.     delete label;
  33.     delete value;
  34. }
  35.  
  36. int cParse::cmp(char *l)
  37. {
  38.     return eq(l, label);
  39. }
  40.  
  41. int cParse::value_true()
  42. {
  43.     return eq(value, "TRUE") || eq(value, "YES");
  44. }
  45.  
  46. void cParse::invalid_line()
  47. {
  48.     error("Invalid line %d: %s = %s", line, label, value);
  49. }
  50.  
  51. int cParse::pgetc()
  52. {
  53.     int c = 0;
  54.     
  55.     for (;;)
  56.     {
  57.         c = *data_current, data_current++;
  58.  
  59.         if (data_current >= data_end)
  60.             return -1;
  61.         
  62.         if (c == '#')
  63.             do 
  64.             {
  65.                 c = *data_current, data_current++;
  66.  
  67.                 if (data_current >= data_end)
  68.                     return -1; 
  69.             }
  70.             while (c != '\n');
  71.             
  72.         if (c == '\n')
  73.             line_no++;
  74.             
  75.         if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
  76.             return c;
  77.     }
  78. }
  79.  
  80. int cParse::get_label()
  81. {
  82.     char *l = lab;
  83.     int c;
  84.     
  85.     for (;;)
  86.     {
  87.         c = pgetc();
  88.         
  89.         if (c == '=' || c == -1 || l >= lab_end)
  90.         {
  91.             *l = 0;
  92.             
  93.             return l != lab;
  94.         } 
  95.         else
  96.             *l = toupper(c), l++;
  97.     }
  98. }
  99.  
  100. int cParse::get_value()
  101. {
  102.     char *v = val;
  103.     int c = 0;
  104.     
  105.     c = pgetc();
  106.     
  107.     for (;;)
  108.     {
  109.         if (c == '\n' || v >= val_end)
  110.             return FALSE;
  111.         
  112.         if (c == ';')
  113.         {
  114.             *v = 0;
  115.             
  116.             return TRUE;
  117.         }
  118.         else
  119.             *v = toupper(c), v++;
  120.         
  121.         c = *data_current, data_current++;
  122.  
  123.         if (data_current >= data_end)
  124.             return FALSE;
  125.     }
  126. }
  127.  
  128. void cParse::parse_file(CFile *in, cParse **list)
  129. {     
  130.     int length = in->GetLength();
  131.  
  132.     // Setup vars
  133.  
  134.     *list = 0;
  135.     line_no = 1;
  136.  
  137.     // Read data and setup pointers
  138.         
  139.     data_start = new char[length];
  140.     in->Read(data_start, length);
  141.     data_current = data_start;
  142.     data_end = data_start + length;
  143.  
  144.     // Parse the file in memory
  145.  
  146.     while (get_label())
  147.     {
  148.         if (!get_value())
  149.             error("Parse error in file: %s, line %d.", in->GetFileName(), line_no);
  150.         
  151.         new cParse (list, lab, val);
  152.     }
  153.  
  154.     // Remove data from memory
  155.  
  156.     delete data_start;
  157. }
  158.  
  159. void cParse::parse_file(char *name, cParse **list)
  160. {
  161.     TRY
  162.     {
  163.         CFile f(name, CFile::modeRead | CFile::shareDenyNone);
  164.  
  165.         parse_file(&f, list);
  166.     }
  167.     CATCH(CFileException, e)
  168.     {
  169.         error("Unable to open %s", name);
  170.     }
  171.     END_CATCH
  172. }
  173.  
  174. char *cParse::get_string(char *name, char *def)
  175. {
  176.     for (cParse *p = this; p != 0; p = (cParse *)p->next)
  177.         if (p->cmp(name))
  178.             return p->value;
  179.         
  180.     return def;
  181. }
  182.  
  183. int cParse::get_int(char *name, int def)
  184. {
  185.     for (cParse *p = this; p != 0; p = (cParse *)p->next)
  186.         if (p->cmp(name))
  187.             return atoi(p->value);
  188.         
  189.     return def;
  190. }
  191.  
  192. fix cParse::get_fix(char *name, fix def)
  193. {
  194.     for (cParse *p = this; p != 0; p = (cParse *)p->next)
  195.         if (p->cmp(name))
  196.             return (fix)atof(p->value);
  197.         
  198.     return def;
  199. }
  200.  
  201. int cParse::get_bool(char *name, int def)
  202. {
  203.     for (cParse *p = this; p != 0; p = (cParse *)p->next)
  204.         if (p->cmp(name))
  205.             return p->value_true();
  206.         
  207.     return def;
  208. }
  209.  
  210. void cParse::get_spots(char *name, cSpot **list)
  211. {
  212.     int x, y;
  213.  
  214.     *list = 0;
  215.  
  216.     for (cParse *p = this; p != 0; p = (cParse *)p->next)
  217.         if (p->cmp(name))
  218.         {
  219.             if(sscanf(p->value, "%d,%d", &x, &y) != 2)
  220.                 p->invalid_line();
  221.  
  222.             new cSpot(list, x, y);
  223.         }
  224. }
  225.